package pk.campustour;

import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.app.AlertDialog;
import android.app.Dialog;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;

public class CameraActivity extends FragmentActivity {
	//
	private static SensorManager mySensorManager;
	private boolean sersorrunning;
	private CompassView myCompassView;
	// Our variables for camera 
    CameraPreview cv;
    FrameLayout alParent;
    ///variables for using gps service
    
	private LocationManager mLocationMgr;
	private Handler mHandler;
	
	private Location mLastLocation;
	private boolean mGeocoderAvailable;
	
	private double latitude;
	private double longitude;
	private long time;
	
	private static final int UPDATE_LASTLATLNG = 4;
	private static final int LAST_UP = 3;
	private static final int UPDATE_LATLNG = 2;
	private static final int UPDATE_ADDRESS = 1;
	
	private static final int SECONDS_TO_UP = 30000;
	private static final int METERS_TO_UP = 10;
	private static final int MINUTES_TO_STALE = 1000 * 60 * 2;
	public String strB;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     ////
        
        //Intent intent=new Intent(this,CompassActivity.class);
        //startActivity(intent);
        ////GPS/////////
        
        mHandler = new Handler() {
    		public void handleMessage(Message msg) {
    			switch (msg.what) {
    			case UPDATE_ADDRESS:
    				//mAddress.setText((String) msg.obj);
    				strB=(String) msg.obj;
    				break;
    			case UPDATE_LATLNG:
    				//mLatLng.setText((String) msg.obj);
    				strB+=(String) msg.obj;
    				break;
    			case LAST_UP:
    				//mLastUp.setText((String) msg.obj);
    				strB+=(String) msg.obj;
    				break;
    			}
    		}
    	};

    	
        mGeocoderAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && Geocoder.isPresent();
    	mLocationMgr = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        
    	
    	//
    	  
	     mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
	     List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
	  
	     if(mySensors.size() > 0){
	      mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_NORMAL);
	      sersorrunning = true;
	      Toast.makeText(this, "Start ORIENTATION Sensor", Toast.LENGTH_LONG).show();
	    
	     }
	     else{
	      Toast.makeText(this, "No ORIENTATION Sensor", Toast.LENGTH_LONG).show();
	      sersorrunning = false;
	      finish();
	     }
    	
    	//////////
        // Set the screen orientation to landscape, because 
        // the camera preview will be in landscape, and if we 
        // don't do this, then we will get a stretched image.
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
        // requesting to turn the title OFF
        requestWindowFeature(Window.FEATURE_NO_TITLE);
 
        // making it full screen
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        //showMessageBox(strB);
    }
 
    public void Load(){
        // Try to get the camera 
        Camera c = getCameraInstance();
 
        // If the camera was received, create the app
        if (c != null){
        	setContentView(R.layout.activity_camera);
            // Create our layout in order to layer the 
            // draw view on top of the camera preview. 
 
            alParent = (FrameLayout) findViewById(R.id.frame1);
        	//alParent = new FrameLayout(this);
            /*alParent.setLayoutParams(new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));*/
            //myCompassView = (CompassView)findViewById(R.id.compassview);
            myCompassView =new CompassView(this);
            // Create a new camera view and add it to the layout
            cv = new CameraPreview(this,c);
            alParent.addView(cv);
            alParent.addView(myCompassView);
            //alParent.addView(myCompassView, 1);
            // Create a new draw view and add it to the layout
            //dv = new DrawView(this);
            //alParent.addView(dv);
 
            // Set the layout as the apps content view
            c.setDisplayOrientation(90);
            //setContentView(alParent);
        }
        // If the camera was not received, close the app
        else {
            Toast toast = Toast.makeText(getApplicationContext(), 
                "Unable to find camera. Closing.", Toast.LENGTH_SHORT);
            toast.show();
            finish();
        }
    }
 
    // This method is strait for the Android API 
    // A safe way to get an instance of the Camera object. 
    public static Camera getCameraInstance(){
        Camera c = null;
 
        try {
            c = Camera.open();// attempt to get a Camera instance
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
            e.printStackTrace();
        }
        return c; // returns null if camera is unavailable
    }
 
    // Override the onPause method so that we 
    // can release the camera when the app is closing.
 
    @Override
    protected void onPause() {
        super.onPause();
        if (cv != null){
            cv.onPause();
            cv = null;
        }
    }
 
    // We call Load in our Resume method, because 
    // the app will close if we call it in onCreate
    @Override
    protected void onResume(){
        super.onResume();
        Load();
        setup();
    }
    @Override
    protected void onStop() {
    	super.onStop();
    	mLocationMgr.removeUpdates(listener);
    }
    private void enableLocationSettings() {
        Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivity(settingsIntent);
    }
    public void onStart() {
    	super.onStart();
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        final boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        
        if (!gpsEnabled) {
        	new EnableGpsDialogFragment().show(getSupportFragmentManager(), "enableGpsDialog");
        }
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
    	super.onSaveInstanceState(outState);
    }
    private void setup() {
    	Location newLocation = null;
    	mLocationMgr.removeUpdates(listener);
    	//mLatLng.setText(R.string.unknown);
    	newLocation = requestUpdatesFromProvider(LocationManager.GPS_PROVIDER, R.string.no_gps_support);

    	// If gps location doesn't work, try network location
    	if (newLocation == null) {
    		newLocation = requestUpdatesFromProvider(LocationManager.NETWORK_PROVIDER, R.string.no_network_support);
    	}
    	
    	if (newLocation != null) {
    		updateUILocation(getBestLocation(newLocation, mLastLocation));
        }
    }
    @Override
	protected void onDestroy() {
	// TODO Auto-generated method stub
	super.onDestroy();

	if(sersorrunning){
	 mySensorManager.unregisterListener(mySensorEventListener);
	}
	}
    

    protected Location getBestLocation(Location newLocation, Location currentBestLocation) {
        if (currentBestLocation == null) {
            return newLocation;
        }
        
        // Check whether the new location fix is newer or older
        long timeDelta = newLocation.getTime() - currentBestLocation.getTime();
        boolean isNewerThanStale = timeDelta > MINUTES_TO_STALE;
        boolean isOlderThanStale = timeDelta < -MINUTES_TO_STALE;
        boolean isNewer = timeDelta > 0;

        if (isNewerThanStale) {
            return newLocation;
        } else if (isOlderThanStale) {
            return currentBestLocation;
        }

        int accuracyDelta = (int) (newLocation.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;

        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(newLocation.getProvider(),
                currentBestLocation.getProvider());

        // Determine location quality using a combination of timeliness and accuracy
        if (isMoreAccurate) {
            return newLocation;
        } else if (isNewer && !isLessAccurate) {
            return newLocation;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return newLocation;
        }
        return currentBestLocation;
    }

    private Location requestUpdatesFromProvider(final String provider, final int errorResId) {
    	Location location = null;
    	if (mLocationMgr.isProviderEnabled(provider)) {
    		mLocationMgr.requestLocationUpdates(provider, SECONDS_TO_UP, METERS_TO_UP, listener);
    		location = mLocationMgr.getLastKnownLocation(provider);
    	} else {
    		Toast.makeText(this, errorResId, Toast.LENGTH_LONG).show();
    	}
    	return location;
    }
    
    private void doReverseGeocoding(Location location) {
        (new ServiceCaller(this)).execute(new Location[] {location});
    }
    
    private void updateUILocation(Location location) {
    	Message.obtain(mHandler, UPDATE_LATLNG, location.getLatitude() + ", " + location.getLongitude()).sendToTarget();
    	if (mLastLocation != null) {
    		Message.obtain(mHandler, UPDATE_LASTLATLNG, mLastLocation.getLatitude() + ", " + mLastLocation.getLongitude()).sendToTarget();
    		longitude=mLastLocation.getLongitude();
    		latitude=mLastLocation.getLatitude();
    	}
    	mLastLocation = location;
    	Date now = new Date();
    	Message.obtain(mHandler, LAST_UP, now.toString()).sendToTarget();
    	time=now.getTime();
    	
        if (mGeocoderAvailable) doReverseGeocoding(location);
    }
    ///message box
    public void showMessageBox(String msg)
	{
		AlertDialog.Builder dlgAlert  = new AlertDialog.Builder(this);
		dlgAlert.setMessage("U r in camera activity"+msg);
		dlgAlert.setPositiveButton("OK", null);
		dlgAlert.setCancelable(true);
		dlgAlert.create().show();
	}
    
    
    private final LocationListener listener = new LocationListener() {
    	@Override
    	public void onLocationChanged(Location location) {
    		updateUILocation(location);
    	}
    	
    	@Override
    	public void onProviderDisabled(String provider) {}
    	
    	public void onProviderEnabled(String provider) {}
    	
    	@Override
    	public void onStatusChanged(String provider, int status, Bundle extras) {}
    };
    private SensorEventListener mySensorEventListener = new SensorEventListener(){

    	@Override
    	public void onAccuracyChanged(Sensor sensor, int accuracy) {
    	 // TODO Auto-generated method stub

    	}

    	@Override
    	public void onSensorChanged(SensorEvent event) {
    	 // TODO Auto-generated method stub
    	 myCompassView.updateDirection((float)event.values[0]);
    	}
    	 };
    	 

   /** Checks whether two providers are the same */
   private boolean isSameProvider(String provider1, String provider2) {
       if (provider1 == null) {
         return provider2 == null;
       }
       return provider1.equals(provider2);
   }
    public class ServiceCaller extends AsyncTask<Location, Void, Void>{
		private ProgressDialog progressDialog;
		Context mContext;
		public ServiceCaller(Context context)
		{
			super();
			mContext = context;
		}
        protected void onPreExecute() {
                progressDialog = ProgressDialog.show(CameraActivity.this,"", "Loading. Please wait...", true);
        }
        @Override
        protected Void doInBackground(Location... params) {
                try {
                        HttpClient hc = new DefaultHttpClient();
                        HttpGet get = new
                        HttpGet("http://search.twitter.com/search.json?q=@" 
                                + getIntent().getStringExtra("Search").toString() + "&rpp=100&page=" + 1);
                        HttpResponse rp = hc.execute(get);
                        if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
                        {
                                String result = EntityUtils.toString(rp.getEntity());
                                JSONObject root = new JSONObject(result);
                                JSONArray sessions = root.getJSONArray("results");
                                for (int i = 0; i < sessions.length(); i++) {
                                        JSONObject session = sessions.getJSONObject(i);
                                //Tweet tweet = new Tweet(session.getString("from_user"),session.getString("text"),session.getString("profile_image_url"));
                                //         tweets.add(tweet);
                                }
                       }
               } catch (Exception e) {
                       Log.e("Camera Activity", "Error loading JSON", e);
               }
               return null;
  }
  @Override
  protected void onPostExecute(Void result) {
          progressDialog.dismiss();
          //Intent intent=new Intent(CameraActivity.this,CompassActivity.class);
          //startActivity(intent);
         showMessageBox(strB);
   }
  
}
    /**
     * Dialog to prompt users to enable GPS on the device.
     */
    
    public class EnableGpsDialogFragment extends DialogFragment {
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return new AlertDialog.Builder(getActivity())
                    .setTitle(R.string.enable_gps)
                    .setMessage(R.string.enable_gps_dialog)
                    .setPositiveButton(R.string.enable_gps, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            enableLocationSettings();
                        }
                    })
                    .create();
        }
    }
}
